const log4js = require('../../../utils/logUtils');
const logger = log4js.getLogger('sip');
const sip = require("sip");
const deviceModel = require("../../../model/device");
const registerAckHandler = require("../ack/registerAck");
const catalogFactory = require("../factory/catalogFactory");
const sipUtils = require("../../../utils/sipUtils");
const deviceCache = require("../../../db/deviceCache");
const config = require("../../../db/config");
const settingModel = require("../../../model/setting");

module.exports={
    /**
     * 处理设备的 register 消息
     */
    async handle(deviceid, rq) {
        const password = settingModel.cache.sip_command_password;
        const realm = settingModel.cache.server_realm;

        // 生成 { deviceid, uri, sip_command_host, sip_command_port }
        let contactObj = this.analysisContact(rq);
        const registerAck = registerAckHandler.generate(rq);
        let deviceInRegistry = deviceCache.registry[deviceid];
        if (!deviceInRegistry) {
            // 生成用户信息 play 是否在播放
            deviceInRegistry = {password, online: false, session: {realm}, play: false};
        }
        // logger.info(`[接收][register] 解析 contactObj=`, contactObj);
        /**
         *  {
         *   deviceid: '41010500002000000005',
         *   uri: 'sip:41010500002000000005@192.168.1.125:5061',
         *   sip_command_host: '192.168.1.125',
         *   sip_command_port: 5061,
         *   protocol: 'UDP'
         * }
         */

        deviceInRegistry = Object.assign(deviceInRegistry, contactObj);

        // 回复注册请求
        const via0 = registerAck.headers.via[0];

        logger.info(`[接收][register] 解析 via0=`, via0);
        if (via0) {
            // 暂时不知道最后一层via是在前面还是后面，这里从0先取一个
            deviceInRegistry.via = registerAck.headers.via;
            // deviceInRegistry.via0 = Object.assign({}, via0);
            // 带内网设备需要端口转发
            if (via0.params && via0.params.rport) {
                deviceInRegistry.sip_command_host = via0.params.received;
                deviceInRegistry.sip_command_port = via0.params.rport;
                deviceInRegistry.uri = `sip:${deviceid}@${deviceInRegistry.sip_command_host}:${deviceInRegistry.sip_command_port}`
            }
        } else {
            deviceInRegistry.via = null;
        }
        sip.send(registerAck);

        deviceInRegistry.last_heart = (new Date()).getTime();
        // 如果通过校验
        if (registerAck.status === 200) {
            rq.headers.contact[0].uri = sipUtils.fixHost(rq.headers.contact[0].uri);
            // contact 暂时只是记录没有使用
            deviceInRegistry.contact = rq.headers.contact;
            deviceInRegistry.online = true;

            // 更新额外信息
            deviceCache.registry[deviceid] = deviceInRegistry;
            await deviceModel.register(deviceid, 1);

            let catalogCmd = await catalogFactory.generate(deviceInRegistry);
            // 校验指令
            const hop = sip.parseUri(catalogCmd.uri);
            if (!hop) {
                logger.error('[发送][catalog]将发送的目录指令校验异常,catalogCmd=', catalogCmd, '设备信息:', config.registry[deviceid], 'deviceId=', deviceid);
            } else {
                // 发送更新目录命令
                sip.send(catalogCmd);
            }
        }else{
            deviceCache.registry[deviceid] = deviceInRegistry;
        }

    },
    /**
     * 解析uri 输出 deviceid,via,uri等信息
     * @param {*} rq
     */
    analysisContact(rq) {
        let from = sip.parseUri(rq.headers.from.uri);
        let to = sip.parseUri(rq.headers.to.uri);
        let deviceid;
        if (from.user === settingModel.cache.sip_command_account) {
            deviceid = to.user;
        } else {
            deviceid = from.user;
        }

        let uri, sip_command_host, sip_command_port;

        if (rq.headers.contact && rq.headers.contact.length > 0) {
            let contact = Object.assign({}, rq.headers.contact[0]);
            /**
             * contact demo: {
             *   name: undefined,
             *   uri: 'sip:34020000001320002204@[::ffff:111.111.111.111]:5060',
             *   params: {}
             * }
             */
            // logger.info(`[接收][register] deviceId=${deviceid} 准备处理register里的contact信息`, contact);
            // 对uri 处理, sip:34020000001320002204@[::ffff:112.31.252.226]:5060 类似这样的uri删除不用的部分
            contact.uri = sipUtils.fixHost(contact.uri);
            let contactObj = sip.parseUri(contact.uri);

            logger.info(`[接收][register] deviceId=${deviceid} 处理后 contactObj=`, contactObj);
            if (contactObj) {
                // 这时的值可能是内网值
                sip_command_host = contactObj.host;
                sip_command_port = contactObj.port;
            } else {
                logger.error(`[接收][register] deviceId=${deviceid} 解析contact失败`, contact);
            }
        }

        uri = `sip:${deviceid}@${sip_command_host}:${sip_command_port}`;
        const protocol = rq.headers.via[0].protocol ? rq.headers.via[0].protocol : 'UDP';
        return {deviceid, uri, sip_command_host, sip_command_port, protocol};  //via: [viaObj] ,
    }
}
